package com.ccteam.fluidmusic.ui.playlist

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.doOnPreDraw
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.paging.LoadState
import androidx.recyclerview.widget.ConcatAdapter
import androidx.recyclerview.widget.GridLayoutManager
import com.ccteam.fluidmusic.NavPlaylistSheetDirections
import com.ccteam.fluidmusic.R
import com.ccteam.fluidmusic.databinding.FragmentPlaylistSheetListBinding
import com.ccteam.fluidmusic.ui.playlist.AddPlaylistBottomSheetFragment.Companion.ADD_PLAYLIST_RESULT
import com.ccteam.fluidmusic.utils.TransitionUtils
import com.ccteam.fluidmusic.view.adapters.PlaylistSheetItemCallback
import com.ccteam.fluidmusic.view.adapters.PlaylistSheetPagingAdapter
import com.ccteam.fluidmusic.view.adapters.paging.CustomLoadStateAdapter
import com.ccteam.fluidmusic.view.adapters.toolbar.ToolbarTitleAdapter
import com.ccteam.fluidmusic.view.base.LightBounceEdgeEffectFactory
import com.ccteam.fluidmusic.widget.AnimToolbarScrollListener
import com.ccteam.shared.result.playlistsheet.PlaylistSheetListItem
import com.ccteam.shared.result.title.ToolbarTitleItem
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

/**
 * 歌单列表页Fragment
 */
@AndroidEntryPoint
class PlaylistSheetListFragment : Fragment() {

    private var _binding: FragmentPlaylistSheetListBinding? = null
    private val binding get() = _binding!!

    private val playlistSheetListViewModel by viewModels<PlaylistSheetListViewModel>()

    @Inject lateinit var lightBounceEdgeEffectFactory: LightBounceEdgeEffectFactory

    private lateinit var dataAdapter: PlaylistSheetPagingAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        exitTransition = TransitionUtils.exitScale
        reenterTransition = TransitionUtils.enterScale
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentPlaylistSheetListBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        postponeEnterTransition()
        view.doOnPreDraw {
            startPostponedEnterTransition()
        }

        binding.toolbarAlbumList.setNavigationOnClickListener {
            findNavController().navigateUp()
        }

        val titleAdapter = ToolbarTitleAdapter()
        titleAdapter.submitList(mutableListOf(ToolbarTitleItem(getString(R.string.online_music_playlistSheet_type))))

        dataAdapter = PlaylistSheetPagingAdapter(playlistSheetCallback)

        val layoutManager = GridLayoutManager(requireContext(),3)
        layoutManager.spanSizeLookup = dataAdapter.spanSizeLookup
        // 设置成表格布局，每行最多3个
        binding.rvPlaylistSheetList.layoutManager = layoutManager

        // 设置回弹效果
        lightBounceEdgeEffectFactory.applyBounceView(binding.rvPlaylistSheetList,this)
        binding.rvPlaylistSheetList.edgeEffectFactory = lightBounceEdgeEffectFactory
        binding.rvPlaylistSheetList.addOnScrollListener(AnimToolbarScrollListener(binding.toolbarTitle))

        binding.rvPlaylistSheetList.adapter = ConcatAdapter(titleAdapter,dataAdapter.withLoadStateFooter(
            CustomLoadStateAdapter(dataAdapter){
                dataAdapter.retry()
            }
        ))

        viewLifecycleOwner.lifecycleScope.launch {
            playlistSheetListViewModel.playlistSheetList.collectLatest {
                dataAdapter.submitData(it)
            }
        }

        playlistSheetListViewModel.showAddPlaylistButton.observe(viewLifecycleOwner, {
            binding.btnAddPlaylist.isVisible = it
        })

        binding.btnAddPlaylist.setOnClickListener {
            findNavController().navigate(PlaylistSheetListFragmentDirections.actionPlaylistSheetListFragmentToAddPlaylistBottomSheetFragment())
        }

        viewLifecycleOwner.lifecycleScope.launch {
            dataAdapter.loadStateFlow.collectLatest {  state ->
                binding.statusView.changeToLoadingStatus(state.refresh is LoadState.Loading)
                binding.statusView.changeToErrorStatus(state.refresh,
                    state.append.endOfPaginationReached && dataAdapter.itemCount < 1)
            }
        }

        binding.statusView.setRetryClickListener {
            dataAdapter.refresh()
        }

    }

    override fun onResume() {
        super.onResume()

        setFragmentResultListener(ADD_PLAYLIST_RESULT){ _,bundle ->
            if(bundle.getBoolean(ADD_PLAYLIST_RESULT)){
                dataAdapter.refresh()
            }
        }
    }


    private val playlistSheetCallback = object: PlaylistSheetItemCallback{
        override fun playlistItemClicked(view: View,item: PlaylistSheetListItem) {

            val transitionName = getString(R.string.playlist_detail_transition_name)
            val extra = FragmentNavigatorExtras(view to transitionName)

            findNavController().navigate(NavPlaylistSheetDirections
                .actionGlobalPlaylistSheetDetailFragment(item.id),extra)
        }

    }



    override fun onDestroyView() {
        super.onDestroyView()

        binding.rvPlaylistSheetList.clearOnScrollListeners()
        _binding = null
    }
}